
#include  <msp430x54xA.h>
#include  "Drivers.h"
#include  "..\ESS_CommonDefine.h"
#include "..\SystemConfigDefineByFlash.h"



static unsigned char flag=0;
static unsigned char checkDelayFlag=0;
static unsigned char bitFlag = 0x01;
//unsigned char TimerCounterForNormal;

////////////////////////////////////////////////////
//TimerFuncForBlink
static int delay_count=0, setDealyCount = 20;
void (*ptr_func)(char enable);
static void implementBlinkDisableFunc(char enable);

////////////////////////////////////////////////////
//Botton function timer
static unsigned char checkButtonFlag=0;
static int button_delay_count=0, setButtonDealyCount = 20;
void (*button_ptr_func)();
static void implementBottonDisableFunc();

////////////////////////////////////////////////////
//Balance function timer
static unsigned char checkBalanceFlag=0;
static int balance_delay_count=0, setBalanceDealyCount = 20;
void (*balance_ptr_func)();
static void implementBalanceDisableFunc();

////////////////////////////////////////////////////
//Protection function timer
static unsigned char checkProtectionFlag=0;
static int protection_delay_count=0, setProtectionDealyCount = 20;
void (*protection_ptr_func)();
static void implementProtectionDisableFunc();


////////////////////////////////////////////////////
//Over Current counting Timer
static unsigned char OverCurrentCountingFlag=0;
static void EmptyOverCurrentCountingFunc();
void (*OverCurrentCounting_ptr_func)();
static int OverCurrentCounting_delay_count=0, setOverCurrentCountingCount = 0;

////////////////////////////////////////////////////
//Watch Dog function counting Timer
static unsigned char WatchDogStartFlag = 0;;
static void EmptyWatchDogFunc();
void (*WatchDog_ptr_func)();
static int WatchDog_delay_count=0, setWatchDogCountingCount = 0;

////////////////////////////////////////////////////////////////////////
//ACLK = n/a, MCLK = SMCLK = TBCLK = default DCO ~1.045MHz
void InitTimerB(){

  //TBCCTL0 = CCIE;                           // TBCCR0 interrupt enabled
  //TBCCR0 = 26350;                           // ~25ms,  1ms = 1054 clk, //error: 1ms = 527 clk
  TBCCR0 = 52700;                           // ~50ms,  1ms = 1054 clk, //error: 1ms = 527 clk
  //TBCTL = TBSSEL_2 + MC_1 + TBCLR ;   // SMCLK, upmode, clear TBR
  TBCTL = TBSSEL_2 + MC_1 + TBCLR + TBIE;   // SMCLK, upmode, clear TBR
                                            // enable interrupt
  ptr_func = implementBlinkDisableFunc;
  //setTimerInterrupt();
  
  button_ptr_func = implementBottonDisableFunc;
  balance_ptr_func = implementBalanceDisableFunc;
  protection_ptr_func = implementProtectionDisableFunc;
  checkButtonFlag = false;
  checkBalanceFlag = false;
  checkProtectionFlag = false;
  
  OverCurrentCounting_ptr_func = EmptyOverCurrentCountingFunc;
  OverCurrentCountingFlag = false;
  
  WatchDog_ptr_func = EmptyWatchDogFunc;
  WatchDogStartFlag = false;
  
  TBCCTL0 |= CCIE;                           // TBCCR0 interrupt enabled
	//TimerCounterForNormal = 0;
} 

void setTimerInterrupt(char enable){
  if(enable){
    //TBCTL |= TBIE;   //  enable interrupt
    TBCCTL0 |= CCIE;                           // TBCCR0 interrupt enabled
  }else{
    TBCCTL0 &= ~CCIE;                           // TBCCR0 interrupt disabled
  }
}
/*
void setCCRInterrupt(){
  TBCCTL1 = OUTMOD_6 + CCIE;                // CCR1 toggle/set
  TBCCR1 = 26350;                           // CCR1 PWM duty cycle
}
*/

static void implementBlinkDisableFunc(char enable){
}
void setTimerFuncForBlink(void (*ptr1)(char enable),char startStatus, unsigned int delay50ms_count){
  setDealyCount = delay50ms_count - 1;
  (*ptr1)(startStatus);
  flag = startStatus;
  ptr_func = ptr1;
  checkDelayFlag = true;
  
  //TBCCTL0 |= CCIE;                           // TBCCR0 interrupt enabled
}
void disableTimerFuncForBlink(){
  checkDelayFlag = false;
  //TBCCTL0 &= ~CCIE;                           // TBCCR0 interrupt enabled
  ptr_func = implementBlinkDisableFunc;
  delay_count = 0;
}

void setButtonTimerToRunFun(void (*ptr1)(), unsigned int delay50ms_count){
  setButtonDealyCount = delay50ms_count;
  button_delay_count = 0;
  button_ptr_func = ptr1;
  checkButtonFlag = true;
}
static void implementBottonDisableFunc(){
}
void setButtonTimer(unsigned int delay50ms_count){
  setButtonDealyCount = delay50ms_count;
  button_ptr_func = implementBottonDisableFunc;
  button_delay_count = 0;
  checkButtonFlag = true;
}


void disableButtonTimer(){
  button_ptr_func = implementBottonDisableFunc;
  checkButtonFlag = false;
  button_delay_count = 0;
  
}
////////////////////////////////////////////////////
//balance
void setBalanceTimerToRunFunc(void (*ptr1)(), unsigned int delay50ms_count){
  setBalanceDealyCount = delay50ms_count;
  balance_delay_count = 0;
  balance_ptr_func = ptr1;
  checkBalanceFlag = true;
}
static void implementBalanceDisableFunc(){
}
void disableBalanceTimer(){
  balance_ptr_func = implementBalanceDisableFunc;
  checkBalanceFlag = false;
  balance_delay_count = 0;
  
}

////////////////////////////////////////////////////
//Protection
void setProtectionTimerToRunFunc(void (*ptr1)(), unsigned int delay50ms_count){
  setProtectionDealyCount = delay50ms_count;
  protection_delay_count = 0;
  protection_ptr_func = ptr1;
  checkProtectionFlag = true;
  //TBCCTL0 |= CCIE;                           // TBCCR0 interrupt enabled
}
static void implementProtectionDisableFunc(){
}
void disableProtectionTimer(){
  protection_ptr_func = implementProtectionDisableFunc;
  checkProtectionFlag = false;
  protection_delay_count = 0;
  //TBCCTL0 &= ~CCIE;                           // TBCCR0 interrupt disabled
 
}

////////////////////////////////////////////////////
//Over Current counting Timer
void setOverCurrentCountingTimerToRunFunc(void (*ptr1)()){
  setOverCurrentCountingCount = CountingTimeBase;
  OverCurrentCounting_delay_count = 0;
  OverCurrentCounting_ptr_func = ptr1;
  OverCurrentCountingFlag = true;
  //TBCCTL0 |= CCIE;                           // TBCCR0 interrupt enabled
}
static void EmptyOverCurrentCountingFunc(){
}
void DisableOverCurrentCountingFunc(){
  OverCurrentCounting_ptr_func = EmptyOverCurrentCountingFunc;
  OverCurrentCountingFlag = false;
  OverCurrentCounting_delay_count = 0;
  //TBCCTL0 &= ~CCIE;                           // TBCCR0 interrupt disabled
}

////////////////////////////////////////////////////
//Watch Dog function
void setWatchDogTimerToRunFunc(void (*watchDogPtr)(), unsigned int delay50ms_count){
  WatchDogStartFlag = false;
  WatchDog_ptr_func = watchDogPtr;
  setWatchDogCountingCount = delay50ms_count;
  WatchDog_delay_count = 0;
}
static void EmptyWatchDogFunc(){
}
void StartWatchDog(){
  WatchDog_delay_count = 0;
  WatchDogStartFlag = true;
}
void StopWatchDog(){
  WatchDog_delay_count = 0;
  WatchDogStartFlag = false;
}

void DisableWatchDogFunc(){
  WatchDog_ptr_func = EmptyWatchDogFunc;
  WatchDogStartFlag = false;
  WatchDog_delay_count = 0;
}






#ifdef _TimerCounterOn_
/////////////////////////////////
//calculation for timing
static unsigned char tf=0;
unsigned int tfc=0;
/////////////////////////////////

void settf(){
  tfc=0;
  tf =1;
}
void stoptf(){
  tf =0;
  TimerCounterForNormal = tfc;
}
void cleartfc(){
  tf =0;
  tfc = 0;
}

#endif
// Timer B0 interrupt service routine (CCIE for CCR0)
#pragma vector=TIMERB0_VECTOR
__interrupt void TIMERB0_ISR (void)
{
  ////////////////////////////////////////////////////////////////////////
  //TimerFuncForBlink
  //P1OUT ^= 0x02;                            // Toggle P1.0 using exclusive-OR
  if(checkDelayFlag && (delay_count++ >= setDealyCount)){
    flag ^= bitFlag;
    //(*ptr)(flag);
    (*ptr_func)(flag);
    delay_count = 0;
  }
  ////////////////////////////////////////////////////////////////////////
  
      if(checkProtectionFlag && (protection_delay_count++ >= setProtectionDealyCount)){
       (*protection_ptr_func)();
        protection_delay_count = 0;
        checkProtectionFlag =false;
        disableProtectionTimer();
      }//if(checkProtectionFlag )   
  ////////////////////////////////////////////////////////////////////////
      if(OverCurrentCountingFlag && (OverCurrentCounting_delay_count++ >= setOverCurrentCountingCount)){
        (*OverCurrentCounting_ptr_func)();
        OverCurrentCounting_delay_count = 0;
      }
}


// Timer_B7 Interrupt Vector (TBIV) handler :(TBIE and CCIE1~CCIE6 for CCR1~CCR6)
#pragma vector=TIMERB1_VECTOR
__interrupt void TIMERB1_ISR(void)
{
  // Any access, read or write, of the TBIV register automatically resets the
  //highest "pending" interrupt flag. 
  switch( __even_in_range(TBIV,14) )
  {
    case  0: break;                          // No interrupt
    case  2:                                 // CCR1 not used
      //P1OUT ^= 0x02;   
      //__delay_cycles(5);                     // Delay required between transaction
/*      
      //if(checkButtonFlag && !getSW1Status() && (button_delay_count++ >= setButtonDealyCount)){ // for demoBoard
      if(checkButtonFlag && getSW1Status() && (button_delay_count++ >= setButtonDealyCount)){
       P1OUT ^= 0x02;   
       (*button_ptr_func)();
        button_delay_count = 0;
        checkButtonFlag =false;
        disableButtonTimer();
      //}else if(getSW1Status()) { //fpr demoboard
      }else if(!getSW1Status()) {
        disableButtonTimer();
      }
*/
      break;
    case  4:                                // CCR2 not used //for balance
    
      //__delay_cycles(5);                     // Delay required between transaction
/*      
      //if(checkButtonFlag && !getSW1Status() && (button_delay_count++ >= setButtonDealyCount)){ // for demoBoard
      if(checkBalanceFlag && getBalanceChannel() > 0 && (balance_delay_count++ >= setBalanceDealyCount)){
       (*balance_ptr_func)();
        balance_delay_count = 0;
        checkBalanceFlag =false;
        disableBalanceTimer();
      //}else if(getSW1Status()) { //fpr demoboard
      }else if(getBalanceChannel() == 0) {
        disableBalanceTimer();
      }    
 */     
       break;
    case  6: break;                          // CCR3 not used
    case  8: break;                          // CCR4 not used
    case 10: break;                          // CCR5 not used
    case 12: break;                          // CCR6 not used
    case 14:                                 // overflow (TBIE)
      //P1OUT ^= 0x03;
      
      //__delay_cycles(5);                     // Delay required between transaction
      
      if(checkButtonFlag ){

      	if(getSW1Status() && (button_delay_count++ >= setButtonDealyCount)){
					//__delay_cycles(5);                     // Delay required between transaction
					(*button_ptr_func)();
					button_delay_count = 0;
					checkButtonFlag =false;
					disableButtonTimer();
				}else if(!getSW1Status()) {
          //disableButtonTimer();
					button_delay_count = 0;
        }
      }//if(checkButtonFlag )
      
      if(checkBalanceFlag ){
        if(getBalanceChannel() > 0 && (balance_delay_count++ >= setBalanceDealyCount)){
         (*balance_ptr_func)();
          balance_delay_count = 0;
          checkBalanceFlag =false;
          disableBalanceTimer();
        }else if(getBalanceChannel() == 0) {
          //disableBalanceTimer();
          balance_delay_count = 0;
        } 
      }//if(checkBalanceFlag )

			////////////////////////////////////////////////////
			//Watch Dog function
      if(WatchDogStartFlag ){
        if(WatchDog_delay_count++ >= setWatchDogCountingCount){
          (*WatchDog_ptr_func)();
        }
      }else{
          WatchDog_delay_count = 0;
      }
     
#ifdef _TimerCounterOn_
      if(tf){
      tfc++;  
      }
#endif
      
      break;
    default: break;
  }
  //__delay_cycles(5);
}

